﻿/**
<code>
  <author name="Zealic" email="zealic(at)gmail.com" type="Creator"/>
</code>
**/
using System;
using System.Reflection;
using System.Reflection.Emit;


namespace Zealib.Mapper
{
    internal static class PocoHelper
    {
        /// <summary>
        /// Emit property assignment.
        /// </summary>
        /// <param name="generator">IL generator</param>
        /// <param name="leftProperty">Left object property .</param>
        /// <param name="rightProperty">Right object property.</param>
        public static void EmitPropertyAssignment(
            ILGenerator generator,
            PropertyInfo leftProperty,
            PropertyInfo rightProperty)
        {
            if (leftProperty == null) throw new ArgumentNullException("leftProperty");
            if (rightProperty == null) throw new ArgumentNullException("rightProperty");
            if (rightProperty.PropertyType.IsAssignableFrom(leftProperty.PropertyType))
            {
                throw new ArgumentException("Left and right PropertyType not matched.");
            }

            generator.Emit(OpCodes.Ldarg_1);
            generator.Emit(OpCodes.Ldarg_0);
            MethodInfo leftGetter = leftProperty.GetGetMethod();
            MethodInfo rightSetter = rightProperty.GetSetMethod();

            if (leftGetter.IsVirtual)
                generator.Emit(OpCodes.Callvirt, leftGetter);
            else
                generator.Emit(OpCodes.Call, leftGetter);

            if (rightSetter.IsVirtual)
                generator.EmitCall(OpCodes.Callvirt, rightSetter, null);
            else
                generator.EmitCall(OpCodes.Call, rightSetter, null);

        }

        public static void EmitStaticCall<TLeft, TRight>(Action<TLeft, TRight> method)
        {
            // Must be static method
            throw new NotImplementedException();
        }

    }
}
